package com.examination.mlib.manager;

import com.yilijk.base.utils.ALog;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by SHICHENG
 * 高并发线程管理
 * Time on 2022/02/16
 *
 * ThreadPoolManager.getInstance().execute(new FutureTask<Object>(thread, null), null);
 */
public class ThreadPoolManager {

    private static final String TAG = ThreadPoolManager.class.getSimpleName();

    private static ThreadPoolManager threadPoolManager = new ThreadPoolManager();

    public static ThreadPoolManager getInstance(){
        return threadPoolManager;
    }

    /**
     * 线程池
     */
    private ThreadPoolExecutor threadPoolExecutor;
    /**
     * 请求队列
     */
    private LinkedBlockingDeque<Future<?>> service = new LinkedBlockingDeque<>();


    //线程池拒绝执行以后，放入阻塞队列
    private RejectedExecutionHandler handler = new RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            try {
                service.put(new FutureTask<Object>(r, null));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    /**
     * 初始化
     */
    private ThreadPoolManager(){
        threadPoolExecutor  = new ThreadPoolExecutor(4, 10,
                10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(4), handler);

        threadPoolExecutor.execute(runnable);
    }

    /**
     * 消费者，不断检测线程队列是否有线程需要执行
     */
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (true){
                FutureTask futureTask = null;

                try {
                    ALog.e(TAG, "队列中等待数量："+service.size());
                    futureTask = (FutureTask)service.take();
                    ALog.e(TAG, "线程池中线程的数量："+threadPoolExecutor.getPoolSize());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if(futureTask !=  null){
                    //消费需要执行的线程
                    threadPoolExecutor.execute(futureTask);
                }

            }
        }
    };

    /**
     * 执行线程任务，延时多少秒执行，相当于生产者，把需要执行的线程放入消息队列
     * @param futureTask
     * @param delayed
     * @param <T>
     */
    public <T> void execute(final FutureTask<T> futureTask, Object delayed){
        if(futureTask != null){
            //延时执行
            if(delayed != null){
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        try {
                            service.put(futureTask);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }, (long)delayed);
            }else {
                //不需要延迟处理
                try {
                    service.put(futureTask);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

